// Copyright (C) Kumo inc. and its affiliates.
// Author: Jeff.li lijippy@163.com
// All rights reserved.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published
// by the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.
//

#pragma once

#include <cstdint>

#include <nebula/types/type_fwd.h>

namespace nebula::util {

    /// \brief The sum of bytes in each buffer referenced by the array
    ///
    /// Note: An array may only reference a portion of a buffer.
    ///       This method will overestimate in this case and return the
    ///       byte size of the entire buffer.
    /// Note: If a buffer is referenced multiple times then it will
    ///       only be counted once.
    TURBO_EXPORT int64_t TotalBufferSize(const ArrayData &array_data);
    /// \brief The sum of bytes in each buffer referenced by the array
    /// \see TotalBufferSize(const ArrayData& array_data) for details
    TURBO_EXPORT int64_t TotalBufferSize(const Array &array);
    /// \brief The sum of bytes in each buffer referenced by the array
    /// \see TotalBufferSize(const ArrayData& array_data) for details
    TURBO_EXPORT int64_t TotalBufferSize(const ChunkedArray &chunked_array);
    /// \brief The sum of bytes in each buffer referenced by the batch
    /// \see TotalBufferSize(const ArrayData& array_data) for details
    TURBO_EXPORT int64_t TotalBufferSize(const RecordBatch &record_batch);
    /// \brief The sum of bytes in each buffer referenced by the table
    /// \see TotalBufferSize(const ArrayData& array_data) for details
    TURBO_EXPORT int64_t TotalBufferSize(const Table &table);

    /// \brief Calculate the buffer ranges referenced by the array
    ///
    /// These ranges will take into account array offsets
    ///
    /// The ranges may contain duplicates
    ///
    /// Dictionary arrays will ignore the offset of their containing array
    ///
    /// The return value will be a struct array corresponding to the schema:
    /// schema({field("start", uint64()), field("offset", uint64()), field("length",
    /// uint64()))
    TURBO_EXPORT turbo::Result<std::shared_ptr<Array>> ReferencedRanges(const ArrayData &array_data);

    /// \brief Returns the sum of bytes from all buffer ranges referenced
    ///
    /// Unlike TotalBufferSize this method will account for array
    /// offsets.
    ///
    /// If buffers are shared between arrays then the shared
    /// portion will be counted multiple times.
    ///
    /// Dictionary arrays will always be counted in their entirety
    /// even if the array only references a portion of the dictionary.
    TURBO_EXPORT turbo::Result<int64_t> ReferencedBufferSize(const ArrayData &array_data);
    /// \brief Returns the sum of bytes from all buffer ranges referenced
    /// \see ReferencedBufferSize(const ArrayData& array_data) for details
    TURBO_EXPORT turbo::Result<int64_t> ReferencedBufferSize(const Array &array_data);
    /// \brief Returns the sum of bytes from all buffer ranges referenced
    /// \see ReferencedBufferSize(const ArrayData& array_data) for details
    TURBO_EXPORT turbo::Result<int64_t> ReferencedBufferSize(const ChunkedArray &array_data);
    /// \brief Returns the sum of bytes from all buffer ranges referenced
    /// \see ReferencedBufferSize(const ArrayData& array_data) for details
    TURBO_EXPORT turbo::Result<int64_t> ReferencedBufferSize(const RecordBatch &array_data);
    /// \brief Returns the sum of bytes from all buffer ranges referenced
    /// \see ReferencedBufferSize(const ArrayData& array_data) for details
    TURBO_EXPORT turbo::Result<int64_t> ReferencedBufferSize(const Table &array_data);

}  // namespace
